// API调用封装

// API基础URL
const API_BASE_URL = process.env.REACT_APP_API_BASE_URL || 'http://localhost:8000/api/v1';

// 存储会话ID
let sessionId = localStorage.getItem('nebula_session_id') || null;

/**
 * 设置会话ID
 * @param {string} id - 新的会话ID 
 */
export const setSessionId = (id) => {
  sessionId = id;
  if (id) {
    localStorage.setItem('nebula_session_id', id);
  } else {
    localStorage.removeItem('nebula_session_id');
  }
};

/**
 * 获取当前会话ID
 * @returns {string|null} 当前会话ID
 */
export const getSessionId = () => sessionId;

/**
 * 发送API请求
 * @param {string} endpoint - API端点
 * @param {string} method - 请求方法(GET, POST等)
 * @param {object} data - 请求数据
 * @param {number} retryCount - 重试次数，默认为0
 * @returns {Promise<any>} 响应数据
 */
const fetchApi = async (endpoint, method = 'GET', data = null, retryCount = 0) => {
  const options = {
    method,
    headers: { 
      'Content-Type': 'application/json',
    }
  };

  // 如果有会话ID，添加到请求头
  if (sessionId && endpoint !== '/connect') {
    options.headers['X-Session-ID'] = sessionId;
  }

  if (data) {
    options.body = JSON.stringify(data);
  }

  console.log(`请求API: ${API_BASE_URL}${endpoint}`, { method, data });
  
  try {
    const response = await fetch(`${API_BASE_URL}${endpoint}`, options);

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({
        detail: '请求失败',
      }));
      
      console.error(`API请求失败: ${API_BASE_URL}${endpoint}`, { 
        status: response.status,
        statusText: response.statusText,
        error: errorData
      });
      
      throw new Error(errorData.detail || '请求失败');
    }

    const responseData = await response.json();
    console.log(`API请求成功: ${API_BASE_URL}${endpoint}`, responseData);
    return responseData;
  } catch (error) {
    console.error(`API请求异常: ${API_BASE_URL}${endpoint}`, error);
    
    // 处理"Failed to fetch"错误，可能是后端服务未启动
    if (error.message === 'Failed to fetch' && retryCount < 2) {
      console.log(`尝试重试请求(${retryCount + 1}/2): ${endpoint}`);
      // 添加延迟后重试
      await new Promise(resolve => setTimeout(resolve, 1000));
      return fetchApi(endpoint, method, data, retryCount + 1);
    }
    
    // 如果是会话相关错误，尝试清除会话状态
    if (error.message.includes('会话') || error.message.includes('连接') || endpoint === '/connection_status') {
      console.log('检测到会话或连接错误，清除会话状态');
      setSessionId(null);
      localStorage.removeItem('nebula_connection_status');
    }
    
    throw error;
  }
};

/**
 * 连接到Nebula数据库
 * @param {object} connectionData - 连接信息
 */
export const connectToDatabase = async (connectionData) => {
  const response = await fetchApi('/connect', 'POST', connectionData);
  // 存储会话ID
  if (response && response.session_id) {
    setSessionId(response.session_id);
  }
  return response;
};

/**
 * 断开数据库连接
 */
export const disconnectFromDatabase = async () => {
  const response = await fetchApi('/disconnect', 'POST');
  // 清除会话ID
  setSessionId(null);
  return response;
};

/**
 * 搜索方法
 * @param {string} methodName - 方法名称
 */
export const searchMethods = (methodName) => {
  return fetchApi('/search', 'POST', { method_name: methodName });
};

/**
 * 获取节点关系
 * @param {string} methodFullName - 方法全名 
 * @param {string} queryType - 查询类型: self, upstream, downstream
 * @param {number} pathDepth - 路径深度，默认为1
 */
export const getNodes = (methodFullName, queryType, pathDepth = 1) => {
  return fetchApi('/nodes', 'POST', {
    method_full_name: methodFullName,
    query_type: queryType,
    path_depth: pathDepth
  });
};

/**
 * 获取节点详情
 * @param {string|number} nodeId - 节点ID
 */
export const getNodeDetail = (nodeId) => {
  // 确保ID是字符串
  const stringNodeId = String(nodeId);
  console.log("调用getNodeDetail API, nodeId:", stringNodeId);
  return fetchApi('/node_detail', 'POST', { node_id: stringNodeId });
};

/**
 * 检查后端连接状态
 * @returns {Promise<any>} 连接状态信息
 */
export const checkConnectionStatus = () => {
  return fetchApi('/connection_status', 'GET');
}; 